<?php
/**
 * config.class
 *
 * script
 *
 * @version:	0.1a
 * @package:	global
 * @author:	alex <qfox@ya.ru> yaroshevich
 * @created:	21 jan 2009
 *
 * @copyright:	(c) 2009 flamebox. All rights reserved.
 */

if( defined( '__CONFIG.CLASS_PHP' ) ) return;
define( '__CONFIG.CLASS_PHP', '0.1a' );

class config extends singleton
{
	// php singleton wrapper
	static public function &__getMe( ) { return parent::__getMe( __CLASS__ ); }
	static public function &instance( ) { return parent::__getMe( __CLASS__ ); }
	
	protected $q = null; // parsed ini file
	protected $file = null; // file name
	protected $files = array( );
	
	protected function parse( $file, $loop = 0 )
	{
		//$gds = array( '', ROOT.'.confs/', __CORE, null );
		//foreach( $gds as $gd ) if( is_readable( $gd.$file ) ) break;
		//if( !is_readable( $gd.$file ) ) return null;
		
		// including @
		$x = parse_ini_file( $file, 1 );
		$this ->files[] = $file;
		
		if( $loop < 2 )
		foreach( array_keys( $x ) as $k )
		if( is_array( $x[$k] ) && isset( $x[$k]['@'] ) )
		{
			$subfile = $this ->fetch_config_file( $x[$k]['@'] );
			if( $subfile !== false )
				$x[$k] += $this ->parse( $subfile, $loop+1 );
			unset( $x[$k]['@'] );
		}
		
		return $x;
	}
	
	protected function fetch_config_file( $file )
	{
		$file = ltrim( $file, '.' );
		$dotfile = '.' . $file;
		$r = fetch_file( ROOTPATH.'.confs/', array( $file, $dotfile ) );
		if( $r !== false )
			return $r;
		
		$r = fetch_file( array( APPPATH, BASEPATH ), $dotfile );
		return $r;
	}
	
	protected function __construct( )
	{
		$this ->file = $file = $this ->fetch_config_file( 'settings' );

		if( $file === false )
			return;
		
		$x = $this ->parse( $this ->file );
		
		$x['host'] = _::pick( @$x['host'], @$_SERVER['SERVER_NAME'], @$_SERVER['HOST_NAME'], 'console' );
		$x['db_url'] = _::pick( @$x['db']['url'], @$x['db_url'], null );
		
		define( 'HOST', $x['host'], 1 );
		define( 'DB_URL', $x['db_url'], 1 );
		
		$x['host_url'] = str_replace( '$host', HOST, _::pick( @$x['host_url'], '/' ) ); // for subdir site
		if( !isset( $x['urls'] ) ) $x['urls'] = array( );
		if( is_array( $x['urls'] ) )
		foreach( $x['urls'] as $k => $v )
		{
		$x['urls'][$k] = str_replace( '$host', HOST, $v );
		}
		
		$x['dirs'] = isset($x['dirs']) && is_array($x['dirs']) ? $x['dirs'] : $x['dir'];
		if( is_array( $x['dirs'] ) )
		foreach( $x['dirs'] as $k => $v )
		{
		$path = str_replace( array( '$root/', '$core/', '$app/', '$exts/', '$site/' ), array( ROOTPATH, BASEPATH, APPPATH, APPPATH, SITEPATH ), $v );
		if( !file_exists( $path ) ) @mkdir( $path, 0750, 1 );
		define( strtoupper( 'DIR_'.$k ), realpath( $path ).'/' );
		//echo strtoupper( 'DIR_'.$k ) . ' is '. constant( strtoupper( 'DIR_'.$k ) )."\n";
		}
		
		// i18n
		if( !isset( $x['locale'] ) ) $x['locale'] = null;
		$this ->locale = $x['locale'];
		if( is_callable( 'gettext' ) && defined( 'DIR_LOCALE' ) )
		{
			$directory = DIR_LOCALE;
			$domains = array_filter( array( @$x['locale']['domain'], 'messages' ) );
			foreach( $domains as $domain )
				bindtextdomain( $domain, $directory );
			
			// Choose domain
			textdomain( reset( $domains ) );
		}
		// i18n configured
		
		
		$this ->q = $x;
	}
	
	public function __set( $p, $v )
	{
		// ->locale__lang => [lang,locale,]
		// ->locale => [locale,]
		//fb::log( $v, $p );

		list( $p, $ns ) = array_reverse( explode( '__', '__'.$p ) );
		if( !( empty($ns) && $p == 'locale' || $ns == 'locale' && !empty( $p ) ) ) return;
		
		if( empty( $ns ) && !is_array( $v ) ) $v = array( 'all' => $v, 'numeric' => 'C' ); // defaults
		if( empty( $ns ) ) { foreach( $v as $k => $vv ) $this ->__set( 'locale__'.$k, $vv ); return; }
		
		// $this ->q[$ns][$p] = $v; // a ono nado?
		
		if( $p == 'lang' ) { putenv( 'LANG='.$v ); $p = 'all'; }
		
		$p = strtoupper( 'LC_'.$p );
		if( defined( $p ) ) setlocale( constant( $p ), $v );
	}
	
	public function __get( $k )
	{
		list( $k, $ns ) = array_reverse( explode( '__', '__'.$k ) );
		
		//exit( 'qwe'.$k );
		return empty( $ns )
			? ( isset($this ->q[$k]) ? $this ->q[$k] : null )
			: ( isset($this ->q[$ns][$k]) ? $this ->q[$ns][$k] : null );
	}

	public function render( $k, $data )
	{
		$r = $this ->$k;
		if( is_null( $r ) ) return null;
		
		if( !is_null( $data ) )
		{
			if( is_string( $data ) )
			{
				$_data = func_get_args( );
				array_shift( $_data );
				$keys = explode( ',', array_shift( $_data ) );
				if( count( $keys ) )
				{
					$data = array( );
					foreach( $keys as $k )
					{
						$data[ $k ] = array_shift( $_data );
					}
				}
			}
			if( is_array( $data ) )
			{
				$r = str_replace( array_map( create_function( '$a', 'return "{{$a}}";' ), array_keys( $data ) ), array_values( $data ), $r );
			}
		}

		// \n
		$r = stripcslashes( $r );
		
		// $host
		if( strpos( $r, '$host' ) !== false )
			$r = str_replace( '$host', $this ->host, $r );
		
		return $r;
	}
	
	
	public function show( )
	{
		return $this ->q;
	}
	
	public function exists( )
	{
		return !is_null( $this ->q );
	}
	
	public function generate( $data )
	{
		$x = parse_ini_file( $this ->file.'.dist', 1 );
		
		$x['db_url'] = sprintf( 'mysqli://%s:%s@%s:3306/%s/?charset=utf8', $data['login'], $data['passwd'], $data['dbhost'], $data['dbname'] );
		foreach( array_keys( $x ) as $k )
		if( isset( $data[$k] ) )
			$x[$k] = $data[$k];
		
		foreach( array_keys( $x['meta'] ) as $k )
		if( isset( $data[$k] ) )
			$x['meta'][$k] = $data[$k];
		
		$newfile = '';
		foreach( $x as $k => $vs )
		{
			if( !is_array( $vs ) )
			{
				$newfile .= sprintf( "%s\t\t= \"%s\"\n", $k, $vs );
				continue;
			}
			
			$newfile .= sprintf( "\n[%s]\n", $k );
			foreach( $vs as $k => $v )
			{
				$newfile .= sprintf( "%s\t\t= \"%s\"\n", $k, $v );
			}
			//$newfile .= "\n";
		}
		//echo "<pre>".$newfile."</pre>";
		
		file_put_contents( $this ->file, $newfile );
	}
	
	public function files( )
	{
		return str_replace( ROOT, './', join( ', ', array_unique( $this ->files ) ) );
	}
}

?>